<?php
/**
 * Created by PhpStorm.
 * User: DD
 * Date: 2016/4/18
 * Time: 14:34
 */

namespace app\common\services;


use app\common\util\Util;
use think\Model;

class BaseService
{
    protected $_modelName = '';
    protected $_viewName = '';
    private $_modelInstance = '';
    private $_viewInstance = '';

    public function __construct($modelName = '', $viewName = '')
    {
        if (!$modelName) {
            $className = get_class($this);
            $pos = strrpos($className, '\\');
            if ($pos) {
                $className = substr($className, $pos + 1, -7);
            }
            $modelName = Util::parseName($className);
        }
        $this->_modelName = $modelName;
        $this->_viewName = $viewName ?: $modelName;
        $this->_init();
    }

    protected function _init()
    {

    }

    public function hasField($fieldName, $tableName = '')
    {
        static $fields;
        if (empty($fields)) {
            $fields = $this->getModelInstance()->getTableInfo('fields', $tableName);
        }
        if (in_array($fieldName, $fields)) {
            return true;
        }
        return false;
    }

    public function getModelInstance()
    {
        if (!$this->_modelInstance) {
            $this->_modelInstance = M($this->_modelName);
        }
        return $this->_modelInstance;
    }

    protected function _getViewInstance()
    {
        if (!$this->_viewInstance) {
            if (strpos($this->_viewName, ' ') !== false) {
                $this->_viewInstance = new Model('', ['true_table_name' => $this->_viewName]);
            } else {
                $this->_viewInstance = M($this->_viewName);
            }
        }
        return $this->_viewInstance;
    }


    public function all($sort, $order, $filterRules)
    {
        $viewInstance = $this->_getViewInstance();
        if (!$sort) {
            $sort = 'id';
        }
        if (!$order) {
            $order = 'desc';
        }
        $filterRules = $this->parseFilterRules($filterRules);
        $viewInstance = $viewInstance->order($sort, $order);
        if ($filterRules) {
            $viewInstance->where(['_complex' => $filterRules]);
        }
        return $viewInstance->select();
    }

    public function pagination($page, $rows, $sort, $order, $filterRules)
    {
        $viewInstance = $this->_getViewInstance();
        if (!$sort) {
            $sort = 'id';
        }
        if (!$order) {
            $order = 'desc';
        }
        $filterRules = $this->parseFilterRules($filterRules);
        if (!empty($filterRules)) {

            $viewInstance->where(['_complex' => $filterRules]);
        }
        $count = $viewInstance->count();
        $viewInstance = $viewInstance->order($sort, $order)->limit(($page - 1) * $rows, $rows);
        if (!empty($filterRules)) {
            $viewInstance->where(['_complex' => $filterRules]);
        }
        $rows = $viewInstance->select();
        return [$count, $rows];
    }

    protected function getSiteId()
    {
        return session('site_id') ?: 0;
    }

    protected function parseFilterRules($filterRules)
    {
        $where = [];
        if (!$filterRules) {
            if ($this->hasField('site_id')) {
                $where['site_id'] = session('site_id') ?: 0;
            }
            return $where;
        }
        $filterRules = json_decode($filterRules, true);
        if ($filterRules) {
            foreach ($filterRules as $rule) {
                $field = $rule['field'];
                $op = !empty($rule['op']) ? $rule['op'] : 'eq';
                $value = $rule['value'];
                if ($op == 'contains') {
                    $val = ['like', '%' . $value . '%'];
                } else {
                    $val = ['eq', $value];
                }
                $where[$field] = $val;
            }
        }
        if ($this->hasField('site_id')) {
            $where['site_id'] = session('site_id') ?: 0;
        }
        return $where;
    }

    public function single($id)
    {
        $viewInstance = $this->_getViewInstance();
        return $viewInstance->find($id);
    }

    public function exportModel($options)
    {
        $rows = [];
        $_POST = $options;
        $filterRules = isset($options['filterRules']) ? $options['filterRules'] : null;
        if ($options['exportType'] == 'all') {
            $rows = $this->all($options['sort'], $options['order'], $filterRules);
        } else if ($options['exportType'] == 'page') {
            $rows = $this->pagination($options['page'], $options['rows'], $options['sort'], $options['order'], $filterRules);
        }
        return $rows;
    }

    public function saveModel($data, $isAdding = null)
    {
        $modelInstance = $this->getModelInstance();
        $pk = $modelInstance->getPk() ?: 'id';
        if (is_null($isAdding)) {
            if (isset($data[$pk]) && $data[$pk]) { // for save
                $isAdding = false;
            } else {
                $isAdding = true;
            }
        }
        $postRules = isset($data['postRules']) ? $data['postRules'] : null;
        if ($postRules) {
            $rules = json_decode($postRules, true);
            if (isset($rules['unique'])) {
                $unique = $rules['unique'];
                if ($unique) {
                    list($field, $title) = explode('=', $unique);
                    if ($isAdding) {
                        if ($modelInstance->where(array($field => $data[$field]))->count() > 0) {
                            return [false, $title . ':【' . $data[$field] . '】已经存在，不能重复添加'];
                        }
                    } else {
                        if ($modelInstance->where(array($pk => array('neq', $data[$pk]), $field => $data[$field]))->count() > 0) {
                            return [false, $title . ':【' . $data[$field] . '】已经存在，不能重复添加'];
                        }
                    }
                }
            }
            unset($data['postRules']);
        }
        if ($isAdding) {
            if ($this->hasField('site_id')) {
                $data['site_id'] = session('site_id') ?: 0;
            }
            return [$modelInstance->auto([
                'create_time' => Util::now(),
                'creator' => LoginService::getLoginUserName()
            ])->add($data)];
        }
        $data['modify_time'] = Util::now();
        $data['modifier'] = LoginService::getLoginUserName();
        $modelInstance->save($data);
        return [true];
    }

    public function deleteModel($ids)
    {
        if (is_string($ids)) {
            $ids = explode(',', $ids);
        } elseif (!is_array($ids)) {
            $ids = [$ids];
        }
        $modelInstance = $this->getModelInstance();
        return $modelInstance->delete($ids);
    }

    public function getComboList($empty = 0)
    {
        $rows = $this->getModelInstance()->field('id value,title as text')->select();
        if ($empty > 0) {
            array_unshift($rows, ['value' => 0, 'text' => '(无)']);
        }
        return $rows;
    }

    public function editField($ids, $data)
    {
        if (is_string($ids)) {
            $ids = explode(',', $ids);
        }
        $pk = $this->getModelInstance()->getPk() ?: 'id';
        $this->getModelInstance()->where([$pk => ['in', $ids]])->save($data);
        return true;
    }


}